﻿using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;

namespace DotNetCommon.Extensions;

/// <summary>
/// <see cref="Type"/>扩展类
/// </summary>
public static class TypeExtensions
{
    private static readonly Type[] _simpleTypes =
    [
        typeof(byte),
        typeof(sbyte),
        typeof(short),
        typeof(ushort),
        typeof(int),
        typeof(uint),
        typeof(long),
        typeof(ulong),
        typeof(float),
        typeof(double),
        typeof(decimal),
        typeof(bool),
        typeof(string),
        typeof(char),
        typeof(Guid),
        typeof(DateTime),
        typeof(DateTimeOffset),
        typeof(TimeSpan),
        typeof(DateOnly),
        typeof(TimeOnly),
        typeof(byte[])
    ];

    /// <summary>
    /// <seealso cref="IsSimpleType"/> 依据 type 是否在其中 + IsEnum 判定为是否是简单类型
    /// </summary>
    public static IReadOnlyList<Type> SimpleTypes => _simpleTypes.AsReadOnly();

    #region TryGetInstanceProperty & TryGetInstanceField
    /// <summary>
    /// 尝试反射返回给定 <paramref name="type"/> 的<c>实例</c>属性, 示例:
    /// <code>
    /// public class Person
    /// {
    ///     public int ParentPub { get; set; }
    /// }
    /// 
    /// public class Student:Person
    /// {
    ///     public string SelfPub { get; set; }
    ///     private string SelfPrivate { get; set; }
    /// }
    /// 
    /// typeof(Person).TryGetInstanceProperty("ParentPub",out var prop); //返回true
    /// typeof(Student).TryGetInstanceProperty("ParentPub",out var prop); //返回true
    /// typeof(Student).TryGetInstanceProperty("SelfPrivate",out var prop); //返回true
    /// typeof(Student).TryGetInstanceProperty("parentpub", out var prop, ignoreCase: true).ShouldBe(true);
    /// typeof(Student).TryGetInstanceProperty("SelfPrivate",out var prop, includePrivate:false); //返回false
    /// typeof(Student).TryGetInstanceProperty("ParentPub",out var prop, inherit:false); //返回false
    /// </code>
    /// </summary>
    /// <param name="type"></param>
    /// <param name="propertyName">属性名称</param>
    /// <param name="property">返回的属性</param>
    /// <param name="inherit">是否返回继承属性</param>
    /// <param name="includePrivate">是否包含私有属性(注意: 最多只能获取自身的私有属性, 无法获取父类的)</param>
    /// <param name="ignoreCase">是否忽略大小写</param>
    public static bool TryGetInstanceProperty(this Type type, string propertyName, out PropertyInfo property, bool inherit = true, bool includePrivate = true, bool ignoreCase = false)
    {
        AssertUtil.NotNull(type);
        AssertUtil.NotNullOrWhiteSpace(propertyName);

        var props = GetInstanceProperties(type, inherit, includePrivate);
        property = props.FirstOrDefault(p => p.Name.Equals(propertyName, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal));

        return property != null;
    }

    /// <summary>
    /// 尝试反射返回给定 <paramref name="type"/> 的<c>实例</c>字段, 示例:
    /// <code>
    /// public class Person
    /// {
    ///     public int ParentPub;
    /// }
    /// 
    /// public class Student:Person
    /// {
    ///     public string SelfPub;
    ///     private string SelfPrivate;
    /// }
    /// 
    /// typeof(Person).TryGetInstanceField("ParentPub",out var field); //返回true
    /// typeof(Student).TryGetInstanceField("ParentPub",out var field); //返回true
    /// typeof(Student).TryGetInstanceField("SelfPrivate",out var field); //返回true
    /// typeof(Student).TryGetInstanceField("parentpub", out var field, ignoreCase: true).ShouldBe(true);
    /// typeof(Student).TryGetInstanceField("SelfPrivate",out var field, includePrivate:false); //返回false
    /// typeof(Student).TryGetInstanceField("ParentPub",out var field, inherit:false); //返回false
    /// </code>
    /// </summary>
    /// <param name="type"></param>
    /// <param name="propertyName">字段名称</param>
    /// <param name="field">返回的字段</param>
    /// <param name="inherit">是否返回继承字段</param>
    /// <param name="includePrivate">是否包含私有字段(注意: 最多只能获取自身的私有字段, 无法获取父类的)</param>
    /// <param name="ignoreCase">是否忽略大小写</param>
    public static bool TryGetInstanceField(this Type type, string propertyName, out FieldInfo field, bool inherit = true, bool includePrivate = true, bool ignoreCase = false)
    {
        AssertUtil.NotNull(type);
        AssertUtil.NotNullOrWhiteSpace(propertyName);

        var fields = GetInstanceFields(type, inherit, includePrivate);
        field = fields.FirstOrDefault(p => p.Name.Equals(propertyName, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal));

        return field != null;
    }
    #endregion

    #region GetInstanceProperties & GetInstanceFields
    /// <summary>
    /// 返回给定 <paramref name="type"/> 的<c>实例</c>属性, 示例:
    /// <code>
    /// class Person
    /// {
    ///     public int ParentPub { get; set; }
    ///     private int ParentPrivate { get; set; }
    ///     protected int ParentProteced { get; set; }
    ///     internal int ParentInternal { get; set; }
    /// }
    /// 
    /// class Student : Person
    /// {
    ///     public int SelfPub { get; set; }
    ///     private int SelfPrivate { get; set; }
    ///     protected int SelfProteced { get; set; }
    ///     internal int SelfInternal { get; set; }
    /// }
    /// 
    /// var func = (bool inherit, bool includePrivate) =>
    /// {
    ///     return typeof(Student).GetInstanceProperties(inherit, includePrivate);
    /// };
    /// func(true, true); //[SelfPub, SelfPrivate, SelfProteced, SelfInternal, ParentPub, ParentProteced, ParentInternal]
    /// func(false, false);//[SelfPub]
    /// func(true, false);//[SelfPub, ParentPub]
    /// func(false, true);//[SelfPub, SelfPrivate, SelfProteced, SelfInternal]
    /// </code>
    /// </summary>
    /// <remarks>此方法可用于返回自身定义的<c>public</c>或<c>non-public </c>属性。</remarks>
    /// <param name="type"></param>
    /// <param name="inherit">是否返回继承属性</param>
    /// <param name="includePrivate">是否包含私有属性(注意: 最多只能获取自身的私有属性, 无法获取父类的)</param>
    public static PropertyInfo[] GetInstanceProperties(this Type type, bool inherit = true, bool includePrivate = true)
    {
        AssertUtil.NotNull(type);
        return GetInstanceProperties(type.GetTypeInfo(), inherit, includePrivate);
    }

    /// <inheritdoc cref="GetInstanceProperties(Type, bool, bool)"/>
    public static PropertyInfo[] GetInstanceProperties(this TypeInfo typeInfo, bool inherit, bool includePrivate)
    {
        AssertUtil.NotNull(typeInfo);

        var flags = BindingFlags.Instance | BindingFlags.Public;
        if (includePrivate) { flags |= BindingFlags.NonPublic; }
        if (!inherit) { flags |= BindingFlags.DeclaredOnly; }

        return typeInfo.GetProperties(flags);
    }

    /// <summary>
    /// 返回给定 <paramref name="type"/> 的<c>实例</c>字段, 示例:
    /// <code>
    /// class Person
    /// {
    ///     public int ParentPub;
    ///     private int ParentPrivate;
    ///     protected int ParentProteced;
    ///     internal int ParentInternal;
    /// }
    /// 
    /// class Student : Person
    /// {
    ///     public int SelfPub;
    ///     private int SelfPrivate;
    ///     protected int SelfProteced;
    ///     internal int SelfInternal;
    /// }
    /// 
    /// var func = (bool inherit, bool includePrivate) =>
    /// {
    ///     return typeof(Student).GetInstanceFields(inherit, includePrivate);
    /// };
    /// func(true, true); //[SelfPub, SelfPrivate, SelfProteced, SelfInternal, ParentPub, ParentProteced, ParentInternal]
    /// func(false, false);//[SelfPub]
    /// func(true, false);//[SelfPub, ParentPub]
    /// func(false, true);//[SelfPub, SelfPrivate, SelfProteced, SelfInternal]
    /// </code>
    /// </summary>
    /// <param name="type"></param>
    /// <param name="inherit">是否返回继承字段</param>
    /// <param name="includePrivate">是否包含私有字段(注意: 最多只能获取自身的私有字段, 无法获取父类的)</param>
    public static FieldInfo[] GetInstanceFields(this Type type, bool inherit = true, bool includePrivate = true)
    {
        AssertUtil.NotNull(type);
        return GetInstanceFields(type.GetTypeInfo(), inherit, includePrivate);
    }

    /// <inheritdoc cref="GetInstanceFields(Type, bool, bool)"/>
    public static FieldInfo[] GetInstanceFields(this TypeInfo typeInfo, bool inherit, bool includePrivate)
    {
        AssertUtil.NotNull(typeInfo);

        var flags = BindingFlags.Instance | BindingFlags.Public;
        if (includePrivate) { flags |= BindingFlags.NonPublic; }
        if (!inherit) { flags |= BindingFlags.DeclaredOnly; }

        return typeInfo.GetFields(flags);
    }
    #endregion

    #region GetPropertiesWithAttribute & GetFieldsWithAttribute
    /// <summary>
    /// 根据条件返回具有 <c>T</c> 特性的属性, 示例:
    /// <code>
    /// [AttributeUsage(AttributeTargets.Property)]
    /// class MyAttribute : Attribute { }
    /// 
    /// class Person
    /// {
    ///     [MyAttribute]
    ///     public int PropWithAttr { get; set; }
    ///     public int Prop { get; set; }
    /// }
    /// 
    /// typeof(Person).GetPropertiesWithAttribute&lt;MyAttribute>()//输出: [PropWithAttr]
    /// </code>
    /// </summary>
    /// <param name="type"></param>
    /// <param name="inherit">是否返回继承的属性</param>
    /// <param name="includePrivate">是否包含私有属性(注意: 最多只能获取自身的私有属性, 无法获取父类的)</param>
    /// <remarks>注意: 参数 <c>inherit</c> 和 <c>includePrivate</c> 控制属性搜索的范围, 参照: <seealso cref="GetInstanceProperties(Type, bool, bool)"/></remarks>
    public static IEnumerable<PropertyInfo> GetPropertiesWithAttribute<T>(this Type type, bool inherit = true, bool includePrivate = true) where T : Attribute
    {
        AssertUtil.NotNull(type);
        return type.GetInstanceProperties(inherit, includePrivate).Where(prop => Attribute.IsDefined(prop, typeof(T)));
    }

    /// <summary>
    /// 根据条件返回具有 <c>T</c> 特性的字段, 示例:
    /// <code>
    /// [AttributeUsage(AttributeTargets.Field)]
    /// class MyAttribute : Attribute { }
    /// 
    /// class Person
    /// {
    ///     [MyAttribute]
    ///     public int FieldWithAttr;
    ///     public int Field;
    /// }
    /// 
    /// typeof(Person).GetFieldsWithAttribute&lt;MyAttribute>()//输出: [FieldWithAttr]
    /// </code>
    /// </summary>
    /// <param name="type"></param>
    /// <param name="inherit">是否返回继承的字段</param>
    /// <param name="includePrivate">是否包含私有字段(注意: 最多只能获取自身的私有字段, 无法获取父类的)</param>
    /// <remarks>注意: 参数 <c>inherit</c> 和 <c>includePrivate</c> 控制字段搜索的范围, 参照: <seealso cref="GetInstanceFields(Type, bool, bool)"/></remarks>
    public static IEnumerable<FieldInfo> GetFieldsWithAttribute<T>(this Type type, bool inherit = true, bool includePrivate = true) where T : Attribute
    {
        AssertUtil.NotNull(type);
        return type.GetInstanceFields(inherit, includePrivate).Where(prop => Attribute.IsDefined(prop, typeof(T)));
    }
    #endregion

    //todo?要不要给 PropertyInfo|fieldInfo 也扩展这种方法, 用来提取注解. 暂时不要, 一般

    /// <summary>
    /// 尝试获取当前 <seealso cref="Type"/> 上定义的所有 <typeparamref name="T"/> 类型的特性数组, 示例:
    /// <code>
    /// [MyAttribute("lisa")]
    /// class Person { }
    /// 
    /// [MyAttribute("jack")]
    /// [MyAttribute("tom")]
    /// class Student : Person { }
    /// 
    /// typeof(Student).TryGetAttributes&lt;MyAttribute>(out MyAttribute[] attributes, inherit: false);//attributes: [jack, tom]
    /// typeof(Student).TryGetAttributes&lt;MyAttribute>(out MyAttribute[] attributes, inherit: true);//attributes: [jack, tom, lisa]
    /// </code>
    /// </summary>
    public static bool TryGetAttributes<T>(this Type type, out T[] attributes, bool inherit = true) where T : Attribute
    {
        var result = Attribute.GetCustomAttributes(type, typeof(T), inherit);

        if (result.Length > 0)
        {
            attributes = result as T[];
            return true;
        }

        attributes = null;
        return false;
    }

    #region IsSubOrAssignableTo & IsParentOrAssignableFrom
    /// <summary>
    /// 判断类、接口、结构体之间的相互继承实现关系, 示例:
    /// <code>
    /// interface IMyInterface{}
    /// 
    /// interface IMyInterfaceOther: IMyInterface{}
    /// 
    /// class MyClassBase{}
    /// 
    /// class MyClassA: MyClassBase, IMyInterface{}
    /// 
    /// typeof(MyClassA).IsSubOrAssignableTo&lt;MyClassBase>() // true
    /// typeof(MyClassA).IsSubOrAssignableTo&lt;IMyInterface>() // true
    /// typeof(MyClassA).IsSubOrAssignableTo&lt;IMyInterfaceOther>() // true
    /// typeof(IMyInterfaceOther).IsSubOrAssignableTo&lt;IMyInterface>() // true
    /// 
    /// //自身也可以判断为true
    /// typeof(MyClassA).IsSubOrAssignableTo&lt;MyClassA>() // true
    /// typeof(IMyInterface).IsSubOrAssignableTo&lt;IMyInterface>() // true
    /// </code>
    /// </summary>
    public static bool IsSubOrAssignableTo<T>(this Type type) => type.IsSubOrAssignableTo(typeof(T));

    /// <summary>
    /// 判断类、接口、结构体之间的相互继承实现关系, 示例:
    /// <code>
    /// interface IMyInterface{}
    /// 
    /// interface IMyInterfaceOther: IMyInterface{}
    /// 
    /// class MyClassBase{}
    /// 
    /// class MyClassA: MyClassBase, IMyInterface{}
    /// 
    /// typeof(MyClassA).IsSubOrAssignableTo(typeof(MyClassBase)) // true
    /// typeof(MyClassA).IsSubOrAssignableTo(typeof(IMyInterface)) // true
    /// typeof(MyClassA).IsSubOrAssignableTo(typeof(IMyInterfaceOther)) // true
    /// typeof(IMyInterfaceOther).IsSubOrAssignableTo(typeof(IMyInterface)) // true
    /// 
    /// //自身也可以判断为true
    /// typeof(MyClassA).IsSubOrAssignableTo(typeof(MyClassA)) // true
    /// typeof(IMyInterface).IsSubOrAssignableTo(typeof(IMyInterface)) // true
    /// </code>
    /// </summary>
    public static bool IsSubOrAssignableTo(this Type type, Type other) => other.IsAssignableFrom(type);

    /// <summary>
    /// 判断类、接口、结构体之间的相互继承实现关系, 示例:
    /// <code>
    /// interface IMyInterface{}
    /// 
    /// interface IMyInterfaceOther: IMyInterface{}
    /// 
    /// class MyClassBase{}
    /// 
    /// class MyClassA: MyClassBase, IMyInterface{}
    /// 
    /// typeof(MyClassBase).IsParentOrAssignableFrom&lt;MyClassA>() // true
    /// typeof(IMyInterface).IsParentOrAssignableFrom&lt;MyClassA>() // true
    /// typeof(IMyInterface).IsParentOrAssignableFrom&lt;IMyInterfaceOther>() // true
    /// 
    /// //自身也可以判断为true
    /// typeof(MyClassA).IsParentOrAssignableFrom&lt;MyClassA>() // true
    /// typeof(IMyInterface).IsParentOrAssignableFrom&lt;IMyInterface>() // true
    /// </code>
    /// </summary>
    public static bool IsParentOrAssignableFrom<T>(this Type type) => type.IsParentOrAssignableFrom(typeof(T));

    /// <summary>
    /// 判断类、接口、结构体之间的相互继承实现关系, 示例:
    /// <code>
    /// interface IMyInterface{}
    /// 
    /// interface IMyInterfaceOther: IMyInterface{}
    /// 
    /// class MyClassBase{}
    /// 
    /// class MyClassA: MyClassBase, IMyInterface{}
    /// 
    /// typeof(MyClassBase).IsParentOrAssignableFrom(typeof(MyClassA)) // true
    /// typeof(IMyInterface).IsParentOrAssignableFrom(typeof(MyClassA)) // true
    /// typeof(IMyInterface).IsParentOrAssignableFrom(typeof(IMyInterfaceOther)) // true
    /// 
    /// //自身也可以判断为true
    /// typeof(MyClassA).IsParentOrAssignableFrom(typeof(MyClassA)) // true
    /// typeof(IMyInterface).IsParentOrAssignableFrom(typeof(IMyInterface)) // true
    /// </code>
    /// </summary>
    public static bool IsParentOrAssignableFrom(this Type type, Type other) => other.IsSubOrAssignableTo(type);
    #endregion

    /// <summary>
    /// 判断当前类型是否是简单类型
    /// </summary>
    /// <remarks>
    /// <para>
    /// 简单类型如下(包含简单类型的可空类型+enum), 参照: <seealso cref="SimpleTypes"/>
    /// </para>
    /// <code>
    /// typeof(byte),
    /// typeof(sbyte),
    /// typeof(short),
    /// typeof(ushort),
    /// typeof(int),
    /// typeof(uint),
    /// typeof(long),
    /// typeof(ulong),
    /// typeof(float),
    /// typeof(double),
    /// typeof(decimal),
    /// typeof(bool),
    /// typeof(string),
    /// typeof(char),
    /// typeof(Guid),
    /// typeof(DateTime),
    /// typeof(DateTimeOffset),
    /// typeof(TimeSpan),
    /// typeof(DateOnly),
    /// typeof(TimeOnly),
    /// typeof(byte[])
    /// </code>
    /// </remarks>
    public static bool IsSimpleType(this Type type)
    {
        AssertUtil.NotNull(type);
        var underlyingType = Nullable.GetUnderlyingType(type);
        type = underlyingType ?? type;

        return Array.IndexOf(_simpleTypes, type) > -1 || type.IsEnum;
    }

    /// <summary>
    /// 判断当前类型是否是数组 <c>T[]</c>, 示例:
    /// <code>
    /// typeof(int[]).IsArrayOf&lt;int>() // true
    /// typeof(object[]).IsArrayOf&lt;object>() // true
    /// typeof(List&lt;int>).IsArrayOf&lt;int>() // false
    /// </code>
    /// </summary>
    public static bool IsArrayOf<T>(this Type type) => type == typeof(T[]);

    /// <summary>
    /// 判断当前类型是否是 <c>List&lt;&gt;</c> 或 <c>IList&lt;&gt;</c>
    /// </summary>
    public static bool IsGenericList(this Type type)
    {
        if (!type.IsGenericType) return false;

        var typeDef = type.GetGenericTypeDefinition();
        return (typeDef == typeof(List<>) || typeDef == typeof(IList<>));
    }

    /// <summary>
    /// 判断当前类型是否是数字类型(如: "int","int?" 均是数字类型 )
    /// </summary>
    public static bool IsNumeric(this Type type)
    {
        if (type is null) return false;

        var underlyingType = type;
        if (type.IsNullable()) underlyingType = Nullable.GetUnderlyingType(type) ?? type;
        if (underlyingType.IsEnum) return false;

        // ReSharper disable once SwitchStatementMissingSomeCases
        switch (underlyingType.GetTypeCode())
        {
            case TypeCode.Byte:
            case TypeCode.Decimal:
            case TypeCode.Double:
            case TypeCode.Int16:
            case TypeCode.Int32:
            case TypeCode.Int64:
            case TypeCode.SByte:
            case TypeCode.Single:
            case TypeCode.UInt16:
            case TypeCode.UInt32:
            case TypeCode.UInt64:
                return true;
            default:
                return false;
        }
    }

    /// <summary>
    /// 获取当前类型的<seealso cref="TypeCode"/>
    /// </summary>
    public static TypeCode GetTypeCode(this Type type)
    {
        if (type == typeof(bool)) { return TypeCode.Boolean; }
        if (type == typeof(char)) { return TypeCode.Char; }
        if (type == typeof(sbyte)) { return TypeCode.SByte; }
        if (type == typeof(byte)) { return TypeCode.Byte; }
        if (type == typeof(short)) { return TypeCode.Int16; }
        if (type == typeof(ushort)) { return TypeCode.UInt16; }
        if (type == typeof(int)) { return TypeCode.Int32; }
        if (type == typeof(uint)) { return TypeCode.UInt32; }
        if (type == typeof(long)) { return TypeCode.Int64; }
        if (type == typeof(ulong)) { return TypeCode.UInt64; }
        if (type == typeof(float)) { return TypeCode.Single; }
        if (type == typeof(double)) { return TypeCode.Double; }
        if (type == typeof(decimal)) { return TypeCode.Decimal; }
        if (type == typeof(DateTime)) { return TypeCode.DateTime; }
        if (type == typeof(string)) { return TypeCode.String; }
        // ReSharper disable once TailRecursiveCall
        // ReSharper disable once ConvertIfStatementToReturnStatement
        if (type.GetTypeInfo().IsEnum) { return Enum.GetUnderlyingType(type).GetTypeCode(); }
        return TypeCode.Object;
    }

    #region GetClassFullName & GetClassGenericFullName
    /// <summary>
    /// 获取当前类型的名称,如: 
    /// <list type="number">
    /// <item>typeof(List&lt;>) => System.Collections.Generic.List&lt;T></item>
    /// <item>typeof(List&lt;Person>) => System.Collections.Generic.List&lt;DotNetCommonTestNamespace.Person></item>
    /// <item>typeof(DemoFu&lt;int?>.DemoZi&lt;long[], double?[]>.DemoSun&lt;string>) => DotNetCommonTestNamespace.DemoFu&lt;int?>.DemoZi&lt;long[],double?[]>.DemoSun&lt;string></item>
    /// </list>
    /// </summary>
    public static string GetClassFullName(this Type type) => GetClassFullName(type, null);
    internal static string GetClassFullName(this Type type, Dictionary<string, string> genericMap = null)
    {
        if (type == null) return null;

        var map = "";
        if (genericMap.IsNotNullOrEmpty())
        {
            var keys = genericMap.Keys.OrderBy(i => i);
            foreach (var item in keys)
            {
                map += $",{item}={genericMap[item]}";
            }
            map = map.Trim(',');
        }

        return classNamesCache.GetOrAdd((type, map), _ =>
        {
            if (shortNames.ContainsKey(type)) return shortNames[type];
            if (type.IsGenericParameter) return genericMap.IsNotNullOrEmpty() && genericMap.ContainsKey(type.Name) ? genericMap[type.Name] : type.Name;
            if (type.IsArray) return GetClassFullName(type.GetElementType(), genericMap) + "[]";
            if (type.IsNullable()) return GetClassFullName(type.GetGenericArguments()[0], genericMap) + "?";

            var types = type.GetGenericArguments().ToList();
            var parents = new List<Type>();

            //获取所有嵌套外层类型
            GetParents(type);
            void GetParents(Type type)
            {
                parents.Add(type);
                if (type.DeclaringType != null)
                {
                    GetParents(type.DeclaringType);
                }
            }

            parents.Reverse();
            //
            var names = new List<string>();
            var counter = 0;
            for (var i = 0; i < parents.Count; i++)
            {
                var parent = parents[i];
                var name = "";
                if (shortNames.TryGetValue(parent, out string value))
                {
                    name = value;
                    names.Add(name);
                    continue;
                }
                else
                {
                    if (!parent.Name.Contains('`'))
                    {
                        name = (i == 0 ? parent.Namespace + "." : "") + parent.Name;
                        names.Add(name);
                        continue;
                    }
                    name = (i == 0 ? parent.Namespace + "." : "") + parent.Name.SplitAndTrimTo<string>("`").FirstOrDefault();
                }
                if (parent.IsGenericType)
                {
                    var defs = parent.GetGenericTypeDefinition().GetGenericArguments();
                    var geneTypes = types.Take(defs.Length).Skip(counter).Select(i =>
                    shortNames.TryGetValue(i, out string value2) ? value2 : (i.IsGenericParameter ? (genericMap.IsNotNullOrEmpty() && genericMap.TryGetValue(i.Name, out string value) ? value : i.Name) : GetClassFullName(i, genericMap))
                    ).ToStringSeparated(", ");
                    if (geneTypes.Length > 0) name += "<" + geneTypes + ">";
                    counter = defs.Length;
                }
                names.Add(name);
            }
            return names.ToStringSeparated(".");
        });
    }
    /// <summary>
    /// 获取当前类型的泛型定义名称以及具化的泛型参数数组,如: 
    /// <list type="number">
    /// <item>typeof(List&lt;>) => (System.Collections.Generic.List&lt;T>,[("T", true, typeof(T))])</item>
    /// <item>typeof(List&lt;Person>) => (System.Collections.Generic.List&lt;T>,[("T", false, typeof(Person))])</item>
    /// </list>
    /// </summary>
    /// <param name="type"></param>
    /// <param name="containsOutOrIn">
    /// <list type="bullet">
    /// <item>为true时,输出: System.Collections.Generic.IEnumerable&lt;out T></item>
    /// <item>为false时,输出: System.Collections.Generic.IEnumerable&lt;T></item>
    /// </list>
    /// </param>
    /// <returns></returns>
    public static (string Name, List<(string name, bool isGeneric, Type type)> GenericTypes) GetClassGenericFullName(this Type type, bool containsOutOrIn = false)
    {
        if (type == null) return (null, null);
        return classNamesCache2.GetOrAdd((type, containsOutOrIn), key =>
        {
            var type = key.type;
            var containsOutOrIn = key.containsOutOrIn;
            if (shortNames2.TryGetValue(type, out string value)) return (value, new List<(string, bool, Type)>());
            if (type.IsGenericParameter) return (type.Name, new List<(string, bool, Type)>());
            if (type.IsArray)
            {
                var tmp = GetClassGenericFullName(type.GetElementType());
                tmp.Name += "[]";
                return tmp;
            }
            var types = type.GetGenericArguments().ToList();
            var parents = new List<Type>();
            //获取所有父类型
            GetParents(type);
            void GetParents(Type type)
            {
                parents.Add(type);
                if (type.DeclaringType != null)
                {
                    GetParents(type.DeclaringType);
                }
            }

            parents.Reverse();
            //
            var geneParaArr = type.GenericTypeArguments.ToList();
            var names = new List<string>();
            var counter = 0;
            var map = new List<(string, bool, Type)>();
            for (var i = 0; i < parents.Count; i++)
            {
                var parent = parents[i];
                var name = "";
                if (shortNames2.TryGetValue(parent, out string value2))
                {
                    name = value2;
                    names.Add(name);
                    continue;
                }
                else
                {
                    name = (i == 0 ? parent.Namespace + "." : "") + parent.Name.SplitAndTrimTo<string>("`").FirstOrDefault();
                }

                if (parent.IsGenericType)
                {
                    var defs = parent.GetGenericTypeDefinition().GetGenericArguments();
                    var geneTypes = defs.Skip(counter).Select(i =>
                    {
                        if (!containsOutOrIn) return i.Name;
                        var k = i.GenericParameterAttributes;
                        if (k.Contains(GenericParameterAttributes.Contravariant)) return $"in {i.Name}";
                        if (k.Contains(GenericParameterAttributes.Covariant)) return $"out {i.Name}";
                        return i.Name;
                    }).ToStringSeparated(", ");
                    defs.Skip(counter).ForEach(k =>
                    {
                        if (geneParaArr.Count > 0)
                        {
                            map.Add((k.Name, false, geneParaArr[0]));
                            geneParaArr.RemoveAt(0);
                        }
                        else
                        {
                            map.Add((k.Name, true, k));
                        }
                    });
                    if (geneTypes.Length > 0) name += "<" + geneTypes + ">";
                    counter = defs.Length;
                }
                names.Add(name);
            }
            return (names.ToStringSeparated("."), map);
        });
    }
    private static readonly Dictionary<Type, string> shortNames = new()
    {
        { typeof(byte),"byte"},{ typeof(byte?),"byte?"},{ typeof(byte[]),"byte[]"},{ typeof(byte?[]),"byte?[]"},
        { typeof(sbyte),"sbyte"},{ typeof(sbyte?),"sbyte?"},{ typeof(sbyte[]),"sbyte[]"},{ typeof(sbyte?[]),"sbyte?[]"},
        { typeof(short),"short"},{ typeof(short?),"short?"},{ typeof(short[]),"short[]"},{ typeof(short?[]),"short?[]"},
        { typeof(ushort),"ushort"},{ typeof(ushort?),"ushort?"},{ typeof(ushort[]),"ushort[]"},{ typeof(ushort?[]),"ushort?[]"},
        { typeof(int),"int"},{ typeof(int?),"int?"},{ typeof(int[]),"int[]"},{ typeof(int?[]),"int?[]"},
        { typeof(uint),"uint"},{ typeof(uint?),"uint?"},{ typeof(uint[]),"uint[]"},{ typeof(uint?[]),"uint?[]"},
        { typeof(long),"long"},{ typeof(long?),"long?"},{ typeof(long[]),"long[]"},{ typeof(long?[]),"long?[]"},
        { typeof(ulong),"ulong"},{ typeof(ulong?),"ulong?"},{ typeof(ulong[]),"ulong[]"},{ typeof(ulong?[]),"ulong?[]"},
        { typeof(float),"float"},{ typeof(float?),"float?"},{ typeof(float[]),"float[]"},{ typeof(float?[]),"float?[]"},
        { typeof(double),"double"},{ typeof(double?),"double?"},{ typeof(double[]),"double[]"},{ typeof(double?[]),"double?[]"},
        { typeof(decimal),"decimal"},{ typeof(decimal?),"decimal?"},{ typeof(decimal[]),"decimal[]"},{ typeof(decimal?[]),"decimal?[]"},
        { typeof(char),"char"},{ typeof(char?),"char?"},{ typeof(char[]),"char[]"},{ typeof(char?[]),"char?[]"},
        { typeof(string),"string"},{ typeof(string[]),"string[]"},
        { typeof(bool),"bool"},{ typeof(bool?),"bool?"},{ typeof(bool[]),"bool[]"},{ typeof(bool?[]),"bool?[]"},
        { typeof(void),"void"},
    };
    private static readonly Dictionary<Type, string> shortNames2 = new()
    {
        { typeof(byte),"byte"},{ typeof(byte[]),"byte[]"},
        { typeof(sbyte),"sbyte"},{ typeof(sbyte[]),"sbyte[]"},
        { typeof(short),"short"},{ typeof(short[]),"short[]"},
        { typeof(ushort),"ushort"},{ typeof(ushort[]),"ushort[]"},
        { typeof(int),"int"},{ typeof(int[]),"int[]"},
        { typeof(uint),"uint"},{ typeof(uint[]),"uint[]"},
        { typeof(long),"long"},{ typeof(long[]),"long[]"},
        { typeof(ulong),"ulong"},{ typeof(ulong[]),"ulong[]"},
        { typeof(float),"float"},{ typeof(float[]),"float[]"},
        { typeof(double),"double"},{ typeof(double[]),"double[]"},
        { typeof(decimal),"decimal"},{ typeof(decimal[]),"decimal[]"},
        { typeof(char),"char"},{ typeof(char[]),"char[]"},
        { typeof(string),"string"},{ typeof(string[]),"string[]"},
        { typeof(bool),"bool"},{ typeof(bool[]),"bool[]"},
        { typeof(void),"void"},
    };
    private static readonly ConcurrentDictionary<(Type type, string map), string> classNamesCache = [];
    private static readonly ConcurrentDictionary<(Type type, bool containsOutOrIn), (string name, List<(string genetypeName, bool isGenericParameter, Type geneType)> genericParameters)> classNamesCache2 = [];
    #endregion

    /// <summary>
    /// 是否是 Nullable 类型的
    /// </summary>
    /// <param name="type"></param>
    public static bool IsNullable(this Type type)
    {
        if (type == null) return false;
        return type.Name == "Nullable`1";
    }

    /// <summary>
    /// 如果是类似 int? 则返回 int, 否则返回自身
    /// </summary>
    public static Type GetNullAbleType(this Type type)
    {
        if (type.IsNullable()) return type.GenericTypeArguments[0];
        return type;
    }

    /// <summary>
    /// 是否是 static
    /// </summary>
    public static bool IsStatic(this Type type)
    {
        if (type == null) return false;
        return type.IsAbstract && type.IsSealed;
    }

    /// <summary>
    /// 获取默认值
    /// </summary>
    public static object GetDefault(this Type type) => type.IsValueType ? Activator.CreateInstance(type) : null;

    /// <summary>
    /// 是否是匿名类型
    /// </summary>
    public static bool IsAnonymous(this Type type) => type?.Name.StartsWith("<>f__AnonymousType") ?? false;

    private static readonly Func<object, object[], object> CreateDefaultEqualityComparer = typeof(EqualityComparer<int>).Assembly.GetTypes().FirstOrDefault(i => i.Name == "ComparerHelpers").GetMethod("CreateDefaultEqualityComparer", BindingFlags.Static | BindingFlags.NonPublic).Compile();
    private static readonly Func<object, object[], object> CreateDefaultComparer = typeof(EqualityComparer<int>).Assembly.GetTypes().FirstOrDefault(i => i.Name == "ComparerHelpers").GetMethod("CreateDefaultComparer", BindingFlags.Static | BindingFlags.NonPublic).Compile();
    private static readonly ConcurrentDictionary<Type, IEqualityComparer> _equalityComparerCaches = [];
    private static readonly ConcurrentDictionary<Type, IComparer> _comparerCaches = [];
    /// <summary>
    /// 获取默认的 IEqualityComparer&lt;T>, 效果同: <seealso cref="EqualityComparer{T}.Default"/>
    /// </summary>
    public static IEqualityComparer GetDefaultEqualityComparer(this Type type)
    {
        return _equalityComparerCaches.GetOrAdd(type, type => CreateDefaultEqualityComparer(null, [type]) as IEqualityComparer);
    }
    /// <summary>
    /// 获取默认的 IComparer&lt;T>, 效果同: <seealso cref="Comparer{T}.Default"/>
    /// </summary>
    public static IComparer GetDefaultComparer(this Type type)
    {
        return _comparerCaches.GetOrAdd(type, type => CreateDefaultComparer(null, [type]) as IComparer);
    }
}